// 懒加载与输入控制相关的全局指令
import { createImageLazyLoader, createComponentLazyLoader, createDataLazyLoader } from "@/utils/lazyLoad";
import { createDebounce, createThrottle, debounce as baseDebounce, throttle as baseThrottle } from "@/utils/debounceThrottle";

// 共享的懒加载实例，避免重复创建观察器
const imageLazyLoader = createImageLazyLoader({ threshold: 0.1, rootMargin: "0px" });
const componentLazyLoader = createComponentLazyLoader({ threshold: 0.1 });
const dataLazyLoader = createDataLazyLoader({ threshold: 0.1 });

// v-lazy: 懒加载图片
export const lazyImage = {
  inserted(el, binding) {
    const src = typeof binding.value === "string" ? binding.value : binding.value?.src;
    if (!src) return;
    imageLazyLoader.observe(el, src, binding.value?.options || {});
    el.__lazy_unobserve__ = () => imageLazyLoader.unobserve(el);
  },
  unbind(el) {
    if (el.__lazy_unobserve__) el.__lazy_unobserve__();
  },
};

// v-lazy-component: 懒加载组件容器
// 用法：<div v-lazy-component="{ name: 'MyComp', loader: () => import('...'), render: (el, comp) => ... }"/>
export const lazyComponent = {
  inserted(el, binding) {
    const { name, loader, options = {} } = binding.value || {};
    if (!name || typeof loader !== "function") return;
    componentLazyLoader.register(name, loader, options);
    componentLazyLoader.observe(el, name);
    el.__lazy_component_cleanup__ = () => componentLazyLoader.unobserve(el);
  },
  unbind(el) {
    if (el.__lazy_component_cleanup__) el.__lazy_component_cleanup__();
  },
};

// v-lazy-data: 懒加载数据
// 用法：<div v-lazy-data="{ name: 'list', loader: fetchFn, render: (el, data) => ... }"/>
export const lazyData = {
  inserted(el, binding) {
    const { name, loader, options = {} } = binding.value || {};
    if (!name || typeof loader !== "function") return;
    dataLazyLoader.register(name, loader, options);
    dataLazyLoader.observe(el, name);
    el.__lazy_data_cleanup__ = () => dataLazyLoader.unobserve(el);
  },
  unbind(el) {
    if (el.__lazy_data_cleanup__) el.__lazy_data_cleanup__();
  },
};

// v-debounce: 事件防抖
// 用法：<input v-debounce:input="{ handler: onInput, wait: 300 }"/>
// 或：<input v-debounce:input="onInput"/>
export const debounce = {
  inserted(el, binding) {
    const event = binding.arg || "input";
    const value = binding.value;
    const wait = typeof value === "object" && value?.wait != null ? value.wait : 300;
    const handler = typeof value === "function" ? value : value?.handler;
    if (typeof handler !== "function") return;

    const wrapped = createDebounce ? createDebounce(handler, wait, {}) : baseDebounce(handler, wait);
    el.__debounce_handler__ = wrapped;
    el.addEventListener(event, wrapped);
  },
  unbind(el, binding) {
    const event = binding.arg || "input";
    if (el.__debounce_handler__) {
      el.removeEventListener(event, el.__debounce_handler__);
      el.__debounce_handler__ = null;
    }
  },
};

// v-throttle: 事件节流
// 用法：<div v-throttle:scroll="{ handler: onScroll, wait: 100 }"/>
// 或：<div v-throttle:scroll="onScroll"/>
export const throttle = {
  inserted(el, binding) {
    const event = binding.arg || "scroll";
    const value = binding.value;
    const wait = typeof value === "object" && value?.wait != null ? value.wait : 100;
    const handler = typeof value === "function" ? value : value?.handler;
    if (typeof handler !== "function") return;

    const wrapped = createThrottle ? createThrottle(handler, wait, {}) : baseThrottle(handler, wait);
    el.__throttle_handler__ = wrapped;
    el.addEventListener(event, wrapped);
  },
  unbind(el, binding) {
    const event = binding.arg || "scroll";
    if (el.__throttle_handler__) {
      el.removeEventListener(event, el.__throttle_handler__);
      el.__throttle_handler__ = null;
    }
  },
};

export default { lazyImage, lazyComponent, lazyData, debounce, throttle };
